package com.tianhua.javs.core.service.translate;

import com.tianhua.javs.client.bean.JavsDocBean;
import com.tianhua.javs.client.bean.JavsTranslateContextBean;
import com.tianhua.javs.core.constant.TagConstants;
import com.tianhua.javs.core.engine.PipelineTranslator;
import com.tianhua.javs.core.parse.DocParseService;
import com.tianhua.javs.core.parse.SegmentSpreadParseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;


/**
 * Description:
 * date: 2022/2/11
 *
 * @author shenshuai
 * @version 1.0.0
 * @since JDK 1.8
 */
@Service
@Slf4j
public class TranslateRouteService {

    @Resource(name = "javsPipelineTranslator")
    private PipelineTranslator javsPipelineTranslator;

    @Resource(name = "assignPipelineTranslator")
    private PipelineTranslator assignPipelineTranslator;


    @Autowired
    private SegmentSpreadParseService segmentSpreadParseService;

    @Autowired
    private DocParseService docParseService;


    /**
     * 这里进行预解析判断当前行大概是什么内容
     * 以及脚本语法检查
     * @param javsTranslateContextBean
     * @param javsRowShellStr 一行javs脚本内容
     */
    private String executeTranslate(JavsTranslateContextBean javsTranslateContextBean, String javsRowShellStr){
        if(StringUtils.isEmpty(javsRowShellStr.trim()) || javsRowShellStr.trim().equals("}") || javsRowShellStr.trim().length() <= 2 ){
            return javsRowShellStr;
        }
        if(javsRowShellStr.trim().startsWith("func")){
            return javsRowShellStr;
        }

        //代码段语句+换行
        if(javsRowShellStr.contains("->") || javsRowShellStr.contains("->{")){
            //这里将一行转换为多行，然后按新的脚本内容进行javs关键字替换
            String [] javsRowSegmentArr = segmentSpreadParseService.spreadMult(javsRowShellStr);
            StringBuilder javaRowSegmengBuilder = new StringBuilder();
            for (String javsRowStr : javsRowSegmentArr){
                String javaRowSegment =  javsPipelineTranslator.translateKeyWard(javsTranslateContextBean, javsRowStr, javsRowStr);
                javaRowSegmengBuilder.append(javaRowSegment+"\n");
            }
            return javaRowSegmengBuilder.toString();
        }

        //赋值语句 --单行
        else if(javsRowShellStr.contains("=")){
            String [] assignArr = javsRowShellStr.split("=");
            if(assignArr.length > 2){
                log.warn("current javs row contains more =, it would be fail. javsRowShellStr = {}",javsRowShellStr);
                return javsRowShellStr;
            }
            //这里假设通过赋值语句解决所有变量声明，变量赋值场景的javs脚本，同时返回一行赋值场景的Java原生代码
            return  assignPipelineTranslator.translateKeyWard(javsTranslateContextBean,javsRowShellStr,assignArr[1]);
        }
        //其他场景下的单行替换
        else {
            return javsPipelineTranslator.translateKeyWard(javsTranslateContextBean, javsRowShellStr, javsRowShellStr);
        }

    }

    /**
     * 预解析流程
     * @param javsTranslateContextBean
     * @param javsRowShellStr
     * @return
     */
    public String preTranslateRoute(JavsTranslateContextBean javsTranslateContextBean, String javsRowShellStr){
        JavsDocBean javsDocBean = docParseService.parseJavsDoc(javsRowShellStr);
        if(!javsDocBean.isDocRow()){
            return executeTranslate(javsTranslateContextBean, javsRowShellStr);
        }

        String javaSegment = executeTranslate(javsTranslateContextBean, javsDocBean.getRowSegment());

        String [] segmentArr = javaSegment.split("\n");
        if(segmentArr.length < 5){
            StringBuilder builder = new StringBuilder();
            for (String segmentStr : segmentArr){
                builder.append(javsDocBean.getBlankPreffix() + TagConstants.DOC_LINE + segmentStr + "\n");
            }
            return builder.toString();
        }

        StringBuilder builder = new StringBuilder(javsDocBean.getBlankPreffix());
        builder.append("/*\n");
        builder.append(javaSegment);
        builder.append("/*\n");
        return builder.toString();
    }



}
